package cn.madis.ymcc.service.impl;

import cn.madis.ymcc.domain.KillActivity;
import cn.madis.ymcc.domain.KillCourse;
import cn.madis.ymcc.mapper.KillActivityMapper;
import cn.madis.ymcc.service.IKillActivityService;
import cn.madis.ymcc.service.IKillCourseService;
import cn.madis.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Zt
 * @since 2022-08-23
 */
@Service
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private IKillCourseService killCorseService;
    @Autowired
    private RedissonClient redissonClient;
    @Override
    public void publish(Long id) {
        //1.活动状态必须是待发布
        KillActivity killActivity = selectById(id);
        boolean b = killActivity.getPublishStatus() == KillActivity.TOBERELEASED;
        AssertUtil.isTrue(b,"秒杀活动状态异常");
        //2.当前系统时间必须小于秒杀最后时间
        boolean after = new Date().before(killActivity.getEndTime());
        AssertUtil.isTrue(after,"秒杀时间已过");
        //3.活动存入redis
        EntityWrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id",id);
        List<KillCourse> killCourses = killCorseService.selectList(wrapper);
        killActivity.setPublishStatus(KillActivity.HAVEPUBLISHED);
        killActivity.setPublishTime(new Date());
        killCourses.stream().forEach(killCourse -> {
            //4.redisson信号量
            String semaphore = id + ":" + killCourse.getCourseId();
            RSemaphore semaphoreTmp = redissonClient.getSemaphore(semaphore);
            boolean b1 = semaphoreTmp.trySetPermits(killCourse.getKillCount());
            if (b1){

               redisTemplate.opsForHash().put(
                       "activity"+killActivity.getId(),
                       killCourse.getId().toString(),
                       killCourse
               );
               killCourse.setPublishStatus(KillCourse.SECKILL);
               killCourse.setPublishTime(killActivity.getPublishTime());
               killCorseService.updateById(killCourse);
           }else {
                //如果添加某一个课程信号量失败人工操作
            }

        });
        updateById(killActivity);
    }
}
